package com.woniu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.exception.RebornException;
import com.woniu.execption.goods.GoodsException;
import com.woniu.execption.goods.GoodsExceptionCode;
import com.woniu.execption.goodstype.GoodsTypeException;
import com.woniu.execption.goodstype.GoodsTypeExceptionCode;
import com.woniu.mapper.GoodsMapper;
import com.woniu.mapper.GoodsTypeMapper;
import com.woniu.model.Goods;
import com.woniu.model.GoodsType;
import com.woniu.params.AddGoodsParam;
import com.woniu.params.ChangeGoodsStateParam;
import com.woniu.params.ListingGoodsParam;
import com.woniu.params.ModifyGoodsParam;
import com.woniu.service.GoodsService;
import com.woniu.service.GoodsTypeService;
import com.woniu.utils.*;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2024年05月25日
 */
@Service
@Transactional
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private GoodsTypeMapper goodsTypeMapper;
    @Autowired
    private GoodsTypeService goodsTypeService;
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private RedissonClient redissonClient;
    /**
     * 分页加载商品信息
     * @param pageNum 第几页
     * @param pageSize 每页条数
     * @return
     */
    @Override
    public Page<Goods> loadAllPage(Integer pageNum, Integer pageSize) {
        //先查redis
//        if (redisUtil.exist(RedisKeyUtil.goodsInfo(pageNum+""))){
//            List<UserAddrees> list =  (List<UserAddrees>) redisUtil.getObject(RedisKeyUtil.userAddressInfo(userId+""));
//            page.setTotal(list.size());
//            // 获取当前页的数据
//            List<UserAddrees> pageContent = list.stream()
//                    .skip((pageNum - 1) * pageSize)
//                    .limit(pageSize)
//                    .collect(Collectors.toList());
//            page.setRecords(pageContent);
//            page.setCurrent(pageNum);
//            page.setSize(pageSize);
//        }
        pageNum = pageNum==null||pageNum==0?1:pageNum;
        pageSize = pageSize==null||pageSize==0?3:pageSize;
        Page<Goods> page = new Page<>(pageNum,pageSize);
        goodsMapper.selectPage(page, new QueryWrapper<Goods>());
        System.out.println(page.getRecords());
        return page;
    }

    /**
     * 删除商品
     * @param ids 传入一个商品id 的集合
     * @return
     */
    @Override
    public List<Goods> delGoods(List<Integer> ids) {

        Set<Integer> setIds = ids.stream().collect(Collectors.toSet());
        if (setIds.size()!=ids.size()) throw new GoodsException(GoodsExceptionCode.GOODS_Id_REPEAT);
        //查询传入的ids的全部商品
        List<Goods> goods = listByIds(ids);
        //判断是否有不存在的商品 和 商品是否已经被删除
        if (goods==null||goods.size()==0) throw new GoodsException(GoodsExceptionCode.GOODS_NOT_EXITS);
        if (goods.size()!=ids.size()) throw new GoodsException(GoodsExceptionCode.GOODS_NOT_EXITS);
        for (Goods good : goods) {
            if (good.getState().longValue()== StateData.GOODS_STATE_DELETE) {
                throw new GoodsException(GoodsExceptionCode.GOODS_STATE_IS_DELETE);
            }
            good.setState(StateData.GOODS_STATE_DISABLE);
        }
        saveBatch(goods);

        return goods;
    }

    /**
     * 修改商品信息
     * @param param
     * @return  返回修改后的商品数据
     */
    @Override
    public Goods modifyGoods(ModifyGoodsParam param) {
        //判断是否下架 下架才能修改商品信息
        Goods goods = this.getOne(new QueryWrapper<Goods>().eq("id", param.getId()));
        if (goods==null) {
            throw new GoodsException(GoodsExceptionCode.GOODS_NOT_EXITS);
        }
        if (goods.getState().longValue()!=StateData.GOODS_STATE_DISABLE) throw new GoodsException(GoodsExceptionCode.GOODS_STATE_NOT_OFF_SHELF);

        GoodsType goodsType = goodsTypeService.getById(param.getTypeId());
        if (goodsType==null) throw new GoodsTypeException(GoodsTypeExceptionCode.GOODSTYPE_NOT_EXITS);

        goods.setName(param.getName());
        goods.setTypeId(param.getTypeId());
        goods.setTypeName(goodsType.getTypeName());
        goods.setImg(param.getImg());
        goods.setNumber(param.getNumber());
        goods.setPrice(param.getPrice());
        goodsMapper.updateById(goods);
        return goods;
    }

    /**
     * 上架商品
     * @param params
     * @return 返回上架后的商品数据
     */
    @Override
    public List<Goods> listing(List<ListingGoodsParam> params) throws Exception {

        Set<Integer> ids = params.stream().map(listingGoodsParam -> listingGoodsParam.getId()).collect(Collectors.toSet());
        //判断是否传入相同的商品id
        if (ids.size() != params.size()) {
            throw new GoodsException(GoodsExceptionCode.GOODS_Id_REPEAT);
        }

        List<Goods> goods = this.listByIds(ids);
        //判断是否有商品不存在
        if (goods==null||goods.size()==0) {
            throw new GoodsException(GoodsExceptionCode.GOODS_NOT_EXITS);
        }
        if (goods.size()!=ids.size()) throw new GoodsException(GoodsExceptionCode.GOODS_NOT_EXITS);


        //以及商品状态是否为下架状态
        for (Goods good : goods) {
            if (good.getState().longValue()!=StateData.GOODS_STATE_DISABLE) throw new GoodsException(GoodsExceptionCode.GOODS_STATE_NOT_OFF_SHELF);
            for (ListingGoodsParam param : params) {
                if (param.getNumber()==0) throw new Exception("非法的上架数量");
                if (param.getId()==good.getId()) {
                    good.setNumber(param.getNumber());
                }
            }
            good.setState(StateData.GOODS_STATE_NORMAL);
        }
        updateBatchById(goods);
        return goods;
    }

    /**
     * 添加商品
     * @param param
     * @return 返回添加后的商品数据
     */
    @Override
    public Goods addGoods(AddGoodsParam param) throws Exception {
        GoodsType goodsType = goodsTypeService.getById(param.getTypeId());
        if (goodsType==null) throw new GoodsTypeException(GoodsTypeExceptionCode.GOODSTYPE_NOT_EXITS);
        Goods goods = this.getOne(new QueryWrapper<Goods>().eq("name", param.getName()));
        RLock lock = redissonClient.getLock(param.getName());
        try {
            if (lock.tryLock(10, 5, TimeUnit.SECONDS)){
                try {
                    if (goods!=null) {
                        throw new GoodsException(GoodsExceptionCode.GOODS_NAME_EXITS);
                    }
                    goods = new Goods();
                    goods.setName(param.getName());
                    goods.setTypeId(goodsType.getId());
                    goods.setTypeName(goodsType.getTypeName());
                    goods.setPrice(param.getPrice());
                    goods.setImg(param.getImg());
                    if (param.getNumber()!=0){
                        goods.setState(StateData.GOODS_STATE_NORMAL);
                        goods.setNumber(param.getNumber());
                    }else {
                        goods.setState(StateData.GOODS_STATE_DISABLE);
                        goods.setNumber(0);
                    }
                    goods.setFreeze(StateData.GOODS_DEFAULT_FREEZE);
                    goodsMapper.insert(goods);
                    return goods;
                }finally {
                    // 确保在业务逻辑完成后释放锁
                    lock.unlock();
                }
            }
        }catch (InterruptedException e){
            //线程意外被中断 的情况 应该记录日志信息 后面改
            e.printStackTrace();
            throw new Exception("线程中断异常");
        }
        return goods;
    }

    /**
     * 下架商品
     * @param id 商品的id
     * @return 返回下架商品的信息
     */
    @Override
    public Goods offShelf(Integer id) {
        Goods goods = this.getById(id);
        if (goods==null) {
            throw new GoodsException(GoodsExceptionCode.GOODS_NOT_EXITS);
        }
        if (goods.getState().intValue()!=StateData.GOODS_STATE_NORMAL) throw new GoodsException(GoodsExceptionCode.GOODS_STATE_ERROR);
        goods.setState(StateData.GOODS_STATE_DISABLE);
        updateById(goods);
        return goods;
    }

    /**
     * 修改商品状态
     * @param param 更改商品状态param
     */
    @Override
    public void changeGoodsState(ChangeGoodsStateParam param) {
        Integer id = param.getId();
        Goods goods = goodsMapper.selectById(id);
        if (goods==null){
            throw new RebornException("不存在的商品",20001);
        }
        if (Objects.equals(goods.getState(), StateData.GOODS_STATE_DELETE)){
            throw new RebornException("该商品已是删除状态",20002);
        }
        GoodsType goodsType = goodsTypeMapper.selectById(goods.getTypeId());
        if (goodsType==null){
            throw new RebornException("不存在的商品类别",30001);
        }
        if (goodsType.getState().equals(StateData.GOODS_STATE_DELETE)){
            throw new RebornException("不存在的商品",20001);
        }
        goods.setState(param.getState());
        goodsMapper.updateById(goods);
    }

    /**
     * 根据id删除商品
     * @param goodsId 商品id
     * @return
     */
    @Override
    public void del(Integer goodsId) {
        Goods goods = goodsMapper.selectById(goodsId);
        if (goods==null){
            throw new RebornException("不存在的商品",50001);
        }
        if(goods.getState().equals(StateData.GOODS_STATE_DELETE)){
            throw new RebornException("商品已是删除状态",50002);
        }
        goods.setState(StateData.GOODS_STATE_DELETE);
        goodsMapper.updateById(goods);
    }


    /**
     * 根据名字模糊查询商品
     * @param name 商品名称
     * @return 返回商品信息集合
     */
    @Override
    public Page<Goods> loadGoodsByName(String name, Integer pageNum, Integer pageSize) {
        // 判断是否使用默认的分页参数
        if (pageNum <= 0 || pageSize <= 0) {
            // 使用默认的分页参数
            pageNum = 1;
            pageSize = 3;
        }
        //开分页
        Page<Goods> page =new Page<>(pageNum, pageSize);
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name",name);
        return goodsMapper.selectPage(page,queryWrapper);
    }


    /**
     * 上传图片成功后,修改商品的图片地址
     * @param id 商品id
     *        img 图片地址
     */
    @Override
    public void changePictor(Integer id, String img) {
        Goods goods = goodsMapper.selectById(id);
        if (goods==null){
            throw new RebornException("不存在的商品",50001);
        }
        if(goods.getState().equals(StateData.GOODS_STATE_DELETE)){
            throw new RebornException("商品已是删除状态",50002);
        }

       goods.setImg(img);
        goodsMapper.updateById(goods);
    }

    @Override
    public String uploadImg(MultipartFile image) throws Exception {
        String filePath = null;
        try {
            String oldName = image.getOriginalFilename();
            String suffix = oldName.substring(oldName.lastIndexOf("."));
            String fileName = UUID.randomUUID().toString();

            filePath = OSSUtil.uploadFile(image.getInputStream(),   fileName+suffix, "jinaisen");
        } catch (Exception e){
            throw new Exception("上传图片异常");
        }

        return filePath;
    }
}